#Boa:Frame:MainFrame

import wx
from wx.lib.anchors import LayoutAnchors
import logging
from pyxmpp.jid import JID
from threading import Thread
from pyxmppmanager import ProVinciImClient
import RequestFrame
import IncomingRequestFrame
import yaml
import threading

# XMPP variables
##server = 'im.bitbrains.nl' #Requires TLS
username = 'testuser4'
server = 'jabber.ambrero.nl'
password = 'test'
resource = 'provinciclient'

#get the logger instance for this app
logger = logging.getLogger('provinci')

def create(parent):
    return MainFrame(parent)

[wxID_MAINFRAME, wxID_MAINFRAMEAVAILABLEBUTTON, wxID_MAINFRAMEBODYTEXTCTRL, 
 wxID_MAINFRAMECHATTEXTCTRL, wxID_MAINFRAMECONNECTBUTTON, 
 wxID_MAINFRAMEEXITBUTTON, wxID_MAINFRAMEGETROSTERBUTTON, 
 wxID_MAINFRAMEIQBUTTON, wxID_MAINFRAMEJIDTEXTCTRL, wxID_MAINFRAMEMAINPANEL, 
 wxID_MAINFRAMEREGISTERBUTTON, wxID_MAINFRAMEREQUESTBUTTON, 
 wxID_MAINFRAMESCROLLEDWINDOW, wxID_MAINFRAMESCROLLEDWINDOW1, 
 wxID_MAINFRAMESENDBUTTON, wxID_MAINFRAMESESSIONBUTTON, 
 wxID_MAINFRAMESTATUSSTATICTEXT, wxID_MAINFRAMESUBSCRIBEBUTTON, 
 wxID_MAINFRAMETOOLBAR1, wxID_MAINFRAMETOSTATICTEXT, wxID_MAINFRAMETOTEXTCTRL, 
 wxID_MAINFRAMEYOUSTATICTEXT, 
] = [wx.NewId() for _init_ctrls in range(22)]

class MainFrame(wx.Frame):
    def _init_ctrls(self, prnt):
        # generated method, don't edit
        wx.Frame.__init__(self, id=wxID_MAINFRAME, name=u'MainFrame',
              parent=prnt, pos=wx.Point(692, 111), size=wx.Size(561, 660),
              style=wx.DEFAULT_FRAME_STYLE, title=u'ProVinci')
        self.SetClientSize(wx.Size(553, 633))
        self.Bind(wx.EVT_CLOSE, self.OnMainFrameClose)

        self.mainPanel = wx.Panel(id=wxID_MAINFRAMEMAINPANEL, name=u'mainPanel',
              parent=self, pos=wx.Point(0, 0), size=wx.Size(553, 633),
              style=wx.TAB_TRAVERSAL)

        self.toolBar1 = wx.ToolBar(id=wxID_MAINFRAMETOOLBAR1, name='toolBar1',
              parent=self.mainPanel, pos=wx.Point(0, 0), size=wx.Size(553, 28),
              style=wx.TB_HORIZONTAL | wx.NO_BORDER)

        self.registerButton = wx.Button(id=wxID_MAINFRAMEREGISTERBUTTON,
              label=u'Register', name=u'registerButton', parent=self.toolBar1,
              pos=wx.Point(8, 0), size=wx.Size(75, 23), style=0)
        self.registerButton.Bind(wx.EVT_LEFT_UP, self.OnRegisterButtonLeftUp)

        self.exitButton = wx.Button(id=wxID_MAINFRAMEEXITBUTTON, label=u'Exit',
              name=u'exitButton', parent=self.toolBar1, pos=wx.Point(472, 0),
              size=wx.Size(75, 23), style=0)
        self.exitButton.Bind(wx.EVT_LEFT_UP, self.OnExitButtonLeftUp)

        self.scrolledWindow = wx.ScrolledWindow(id=wxID_MAINFRAMESCROLLEDWINDOW,
              name=u'scrolledWindow', parent=self.mainPanel, pos=wx.Point(16,
              448), size=wx.Size(528, 112), style=wx.HSCROLL | wx.VSCROLL)
        self.scrolledWindow.SetBackgroundColour(wx.Colour(255, 0, 0))

        self.bodyTextCtrl = wx.TextCtrl(id=wxID_MAINFRAMEBODYTEXTCTRL,
              name=u'bodyTextCtrl', parent=self.scrolledWindow, pos=wx.Point(8,
              9), size=wx.Size(512, 90), style=wx.TE_WORDWRAP | wx.VSCROLL,
              value=u'body')

        self.getRosterButton = wx.Button(id=wxID_MAINFRAMEGETROSTERBUTTON,
              label=u'Roster', name=u'getRosterButton', parent=self.toolBar1,
              pos=wx.Point(88, 0), size=wx.Size(75, 23), style=0)
        self.getRosterButton.Bind(wx.EVT_LEFT_UP, self.OnGetRosterButtonLeftUp)
        self.getRosterButton.Bind(wx.EVT_BUTTON, self.OnGetRosterButtonButton,
              id=wxID_MAINFRAMEGETROSTERBUTTON)

        self.jidTextCtrl = wx.TextCtrl(id=wxID_MAINFRAMEJIDTEXTCTRL,
              name=u'jidTextCtrl', parent=self.mainPanel, pos=wx.Point(56, 40),
              size=wx.Size(232, 21), style=0, value=u'testuser4')

        self.connectButton = wx.Button(id=wxID_MAINFRAMECONNECTBUTTON,
              label=u'Connect', name=u'connectButton', parent=self.mainPanel,
              pos=wx.Point(296, 40), size=wx.Size(75, 23), style=0)
        self.connectButton.Bind(wx.EVT_LEFT_UP, self.OnConnectButtonLeftUp)

        self.sendButton = wx.Button(id=wxID_MAINFRAMESENDBUTTON, label=u'Send',
              name=u'sendButton', parent=self.mainPanel, pos=wx.Point(464, 568),
              size=wx.Size(75, 23), style=0)
        self.sendButton.Bind(wx.EVT_LEFT_UP, self.OnSendButtonLeftUp)

        self.toTextCtrl = wx.TextCtrl(id=wxID_MAINFRAMETOTEXTCTRL,
              name=u'toTextCtrl', parent=self.mainPanel, pos=wx.Point(64, 88),
              size=wx.Size(384, 21), style=0,
              value=u'testuser3@jabber.ambrero.nl/provinciclient')

        self.toStaticText = wx.StaticText(id=wxID_MAINFRAMETOSTATICTEXT,
              label=u'To', name=u'toStaticText', parent=self.mainPanel,
              pos=wx.Point(24, 88), size=wx.Size(15, 16), style=0)
        self.toStaticText.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL,
              False, u'MS Shell Dlg 2'))

        self.youStaticText = wx.StaticText(id=wxID_MAINFRAMEYOUSTATICTEXT,
              label=u'You', name=u'youStaticText', parent=self.mainPanel,
              pos=wx.Point(24, 40), size=wx.Size(21, 16), style=0)
        self.youStaticText.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL,
              False, u'MS Shell Dlg 2'))

        self.statusStaticText = wx.StaticText(id=wxID_MAINFRAMESTATUSSTATICTEXT,
              label=u'Not connected', name=u'statusStaticText',
              parent=self.mainPanel, pos=wx.Point(5, 618), size=wx.Size(70, 13),
              style=0)

        self.scrolledWindow1 = wx.ScrolledWindow(id=wxID_MAINFRAMESCROLLEDWINDOW1,
              name='scrolledWindow1', parent=self.mainPanel, pos=wx.Point(16,
              120), size=wx.Size(528, 312), style=wx.HSCROLL | wx.VSCROLL)
        self.scrolledWindow1.SetBackgroundColour(wx.Colour(0, 255, 0))
        self.scrolledWindow1.SetLabel(u'scrolledWindow1')

        self.chatTextCtrl = wx.TextCtrl(id=wxID_MAINFRAMECHATTEXTCTRL,
              name=u'chatTextCtrl', parent=self.scrolledWindow1, pos=wx.Point(8,
              12), size=wx.Size(512, 288),
              style=wx.TE_MULTILINE | wx.VSCROLL | wx.TE_WORDWRAP, value=u'')

        self.availableButton = wx.Button(id=wxID_MAINFRAMEAVAILABLEBUTTON,
              label=u'Available', name=u'availableButton',
              parent=self.mainPanel, pos=wx.Point(456, 40), size=wx.Size(75,
              23), style=0)
        self.availableButton.Bind(wx.EVT_LEFT_UP, self.OnAvailableButtonLeftUp)

        self.subscribeButton = wx.Button(id=wxID_MAINFRAMESUBSCRIBEBUTTON,
              label=u'Subscribe', name=u'subscribeButton',
              parent=self.mainPanel, pos=wx.Point(456, 88), size=wx.Size(75,
              23), style=0)
        self.subscribeButton.Bind(wx.EVT_LEFT_UP, self.OnSubscribeButtonLeftUp)

        self.sessionButton = wx.Button(id=wxID_MAINFRAMESESSIONBUTTON,
              label=u'Start session', name=u'sessionButton',
              parent=self.mainPanel, pos=wx.Point(376, 41), size=wx.Size(75,
              23), style=0)
        self.sessionButton.Bind(wx.EVT_LEFT_UP, self.OnSessionButtonLeftUp)

        self.requestButton = wx.Button(id=wxID_MAINFRAMEREQUESTBUTTON,
              label=u'new request', name=u'requestButton',
              parent=self.mainPanel, pos=wx.Point(240, 592), size=wx.Size(75,
              23), style=0)
        self.requestButton.Bind(wx.EVT_LEFT_UP, self.OnNewRequestButtonLeftUp)

        self.iqButton = wx.Button(id=wxID_MAINFRAMEIQBUTTON, label=u'IQ',
              name=u'iqButton', parent=self.toolBar1, pos=wx.Point(168, 0),
              size=wx.Size(75, 23), style=0)
        self.iqButton.Bind(wx.EVT_LEFT_UP, self.OnIqButtonLeftUp)

    def __init__(self, parent):
        self._init_ctrls(parent)       

    def exit(self):
        logger.debug('exit')
        try:
            self.im.exit()
        except:
            pass
        self.Destroy()        
        
    def register(self):
        logger.debug("registering...")
        jid = JID(username, server, resource)
        im = ProVinciImClient(jid=jid, auth_methods=["sasl:DIGEST-MD5","digest"])
        im.connect(register=True)
        
    def connect(self):
        logger.debug("connecting...")
        if self.jidTextCtrl.Value:
            username = self.jidTextCtrl.Value
        self.jid = JID(username, server, resource)
        self.im = ProVinciImClient(parent=self,jid=self.jid, password=password, auth_methods=["sasl:DIGEST-MD5","digest"])
        self.im.connect()        
        thrd = Thread(target=self.im.loop)
        thrd.start()

    # Call back ========================================================================================================

    def connected(self):
        logger.debug("connected")        
        self.connectButton.Disable()
        self.jidTextCtrl.Disable()
        self.statusStaticText.Label = 'connected'
##        logger.debug(self.im.disco_identity)
##        logger.debug(self.im.disco_info.as_xml())
##        logger.debug(self.im.disco_items.as_xml())
            
    def sessionStarted(self):
        self.statusStaticText.Label = 'Session started'        
                
    def onMessage(self, stanza):
        body = stanza.get_body()
        self.chatTextCtrl.AppendText('\n' + JID(stanza.get_from_jid()).node + ':\n' + body)
        
    def sendRequest(self, request):
        logger.debug('sendRequest: \n' + yaml.dump(request, default_flow_style=False))
        try:
            self.im.sendMessage(self.toTextCtrl.Value, yaml.dump(request))
        except Exception, e:
            logger.error(e)
                    
    def sendResponse(self, response):
        logger.debug('sendResponse: \n' + yaml.dump(response, default_flow_style=False))
        try:
            self.im.sendMessage(self.toTextCtrl.Value, yaml.dump(response))
        except Exception, e:
            logger.error(e)
            
    def onRequest(self, request):
        logger.debug("onRequest")        
        incomingRequestFrame = IncomingRequestFrame.create(self, request)
        incomingRequestFrame.Show()
        
    def onResponse(self, response):
        logger.debug("onResponse")        
        dlg = wx.MessageDialog(self, str(response), 'Response', wx.OK | wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()
        
    
    # Event Handlers ===================================================================================================
    
    def OnRegisterButtonLeftUp(self, event):
        logger.debug('OnRegisterButtonLeftUp')
        self.register()
        event.Skip()

    def OnConnectLeftUp(self, event):
        self.connect()
        event.Skip()

    def OnSendButtonLeftUp(self, event):
        try:
            self.im.sendMessage(self.toTextCtrl.Value, self.bodyTextCtrl.Value)
        except Exception, e:
            logger.error(e)
        event.Skip()

    def OnMainFrameClose(self, event):
        self.exit()
        event.Skip()

    def OnExitButtonLeftUp(self, event):
        self.exit()
        event.Skip()

    def OnGetRosterButtonLeftUp(self, event):
        self.im.request_roster()
        event.Skip()

    def OnConnectButtonLeftUp(self, event):
        self.connect()
        event.Skip()

    def OnAvailableButtonLeftUp(self, event):
        self.im.setStatus(to_jid=None, stanza_type='available', show='chat', status='ProVinci in da house')
        event.Skip()

    def OnSubscribeButtonLeftUp(self, event):
        self.im.subscribe(self.toTextCtrl.Value)
        event.Skip()

    def OnIqButtonLeftUp(self, event):
        self.im.sendGetIq(self.toTextCtrl.Value, self.bodyTextCtrl.Value)
        event.Skip()

    def OnSessionButtonLeftUp(self, event):
        self.im.request_session()
        event.Skip()

    def OnNewRequestButtonLeftUp(self, event):
        self.requestFrame = RequestFrame.create(self)
        self.requestFrame.Show()
        event.Skip()

    def OnGetRosterButtonButton(self, event):
        event.Skip()
